<?php
namespace Api;
use Controller\MchOrder;
use Controller\Member;
use Kuyuan\WqCore\api\Api;
use Kuyuan\WqCore\util\DB;
use Kuyuan\WqCore\util\Util;
use Kuyuan\WqCore\wx\Pay;

/**
 * 追加红包
 * Class SendRed
 * @package Api
 */
class AddTo extends Api
{
    private $Red = null;

    private $Member = null;

    // 接收的红包数据
    private $_data = array();
    // 红包id
    private $_red_id = 0;
    // 红包数据
    private $_red = array();
    // 追加记录id
    private $_add_to_id = 0;

    public function __construct()
    {
        parent::__construct();
        $this->Red = $this->newController("Red");
        if(isset($this->_gpc["data"])) $this->_data = $this->_gpc["data"];
        if(isset($this->_gpc["red_id"])) $this->_red_id = $this->_gpc["red_id"];
        if(isset($this->_gpc["add_to_id"])) $this->_add_to_id = $this->_gpc["add_to_id"];
    }

    /**
     * 追加红包
     */
    public function index()
    {
        Util::appointPost();
        $_result = array();
        try {
            // 获取红包数据
            $this->_red = $this->Red->get($this->_red_id);
            // 验证红包是否存在
            if(!$this->_red || ($this->_red["status"] != 2 && $this->_red["status"] != 4)) {
                throw new \Exception("红包不存在",100);
            }
            // 验证红包所有者是不是当前操作的用户
            if(!$this->checkOwnerUser()) {
                throw new \Exception("非法操作",100);
            }
            // 新增追加记录
            $this->_add_to_id = $this->createAddToRecord();
            if(!$this->_add_to_id) {
                throw new \Exception("新增追加记录失败",103);
            }
            $_pay_result = $this->pay();
            if($_pay_result) {
                if($_pay_result === true) {
                    $_result = array("code"=>0,"data"=>$this->_add_to_id);
                } else {
                    $_result = array("code"=>0,"data"=>$this->_add_to_id,"pay_params"=>$_pay_result);
                }
            } else {
                throw new \Exception("支付失败",104);
            }
        } catch (\Exception $e) {
            $_result = array("code"=>$e->getCode(),"err_msg"=>$e->getMessage());
        }
        Util::returns($_result);
    }

    /**
     * 支付发红包金额，并且返回支付参数
     */
    private function pay()
    {
        $SettingFinance = $this->newController("SettingFinance");
        $_setting_finance = $SettingFinance->find();
        $this->Member = $this->newController("Member");
        // 判断是否支持余额发红包,并且判断用户余额是否足够
        if($_setting_finance["balance_send"]
            &&
            $this->Member->finance() >= $this->_data["pay"]
        ) {
            // 用户余额足够，扣除用户余额
            return $this->expend();
        } else {
            // 获取微信支付参数
            return $this->getWxPayParams();
        }
    }

    /**
     * 扣除余额，余额支付后直接将红包金额和数量追加到红包内
     */
    private function expend()
    {
        DB::begin();
        try{
            $this->Member->financeHandle($this->_data["pay"],false);
            $AddTo = $this->newController("Addto");
            $AddTo->edit($this->_add_to_id,array("status"=>2,"pay_type"=>1));
            $this->addTo();
            DB::commit();
        }catch (\PDOException $e) {
            DB::back();
            return false;
        }
        return true;
    }

    /**
     * 追加红包
     */
    private function addTo()
    {
        $this->Red->addition($this->_red_id,"number",$this->_data["number"]);
        if($this->_red["type"] == 2){
            // 手气红包
            $this->Red->addition($this->_red_id,"money",$this->_data["money"]);
        }
    }

    /**
     * 获取微信支付参数
     */
    private function getWxPayParams()
    {
        $MchOrder = $this->newController("MchOrder");
        $Setting = $this->newController("Setting");
        $_setting = $Setting->find();
        $_order = [
            'out_trade_no' => $MchOrder->create($this->_data["pay"],$this->_add_to_id,"add"),
            'total_fee' => KUYUAN_DEBUG ? 101 : $this->_data["pay"]*100,
            'body' => $_setting["app_name"]."追加红包",
            'openid' => $this->Member->uidToOpenid(),
        ];
        return \Yansongda\Pay\Pay::wechat(Pay::config())->mp($_order);
    }

    /**
     * 验证红包所属用户
     */
    private function checkOwnerUser()
    {
        $_result = true;
        if($this->_red["uid"] != Util::uid()) {
            $_result = false;
        }
        return $_result;
    }

    /**
     * 新增追加记录
     */
    private function createAddToRecord()
    {
        // 创建追加记录
        $AddTo = $this->newController("Addto");
        $_add_to_data = array(
            "red_id" => $this->_red_id,
            "number" => $this->_data["number"],
            "charge" => $this->_data["charge"],
            "pay" => $this->_data["pay"]
        );
        if(isset($this->_data["money"])) {
            $_add_to_data["money"] = $this->_data["money"];
        }
        return $AddTo->add($_add_to_data);
    }

    /**
     * 发红包微信支付成功
     */
    public function wxPaySuccess()
    {
        if(!$this->checkWxPay()) {
            Util::returns(array("code"=>105));
        }
        $Mch = $this->newController("MchOrder");
        DB::begin();
        try{
            $Mch->edit($this->_add_to_id,array("status"=>2),"add");
//            $AddTo = $this->newController("Addto");
//            $AddTo->edit($this->_add_to_id,array("status"=>2,"pay_type"=>2));
            $_result = array("code"=>0);
            DB::commit();
        }catch (\PDOException $e) {
            $_result = array("code"=>103);
            DB::commit();
        }
        Util::returns($_result);
    }

    /**
     * 验证微信支付
     */
    private function checkWxPay()
    {
        $Mch = $this->newController("MchOrder");
        $_mch_order = $Mch->find($this->_add_to_id,"add");
        // 查询微信商户订单
        $_result = \Yansongda\Pay\Pay::wechat(Pay::config())->find($_mch_order["order_id"]);
        // 微信商户订单支付状态是否成功
        if($_result->trade_state != "SUCCESS") {
            $this->wxPayAbnormal($_mch_order["order_id"]);
            return false;
        }
        // 微信商户支付金额和本地订单金额是否一致（红包支付金额+本地微信支付订单金额+微信商户支付金额是否一致）
        // 判断是否为沙箱测试模式
        if($_result->device_info != "sandbox") {
            if((floor($_result->cash_fee) != floor($_mch_order["money"]*100))) {
                // 订单异常
                $this->wxPayAbnormal($_mch_order["order_id"]);
                return false;
            }
            $AddTo = $this->newController("Addto");
            if(floor($_result->cash_fee) != floor($AddTo->value($this->_add_to_id,"pay")*100)) {
                // 红包金额异常
                $this->wxPayAbnormal($_mch_order["order_id"]);
                return false;
            }
        }
        return true;
    }

    /**
     * 微信支付异常处理
     * @param int $_order_id 订单id
     */
    private function wxPayAbnormal($_order_id)
    {
        $Mch = $this->newController("MchOrder");
        $Mch->edit($this->_add_to_id,array("status"=>8),"add");
        $AddTo = $this->newController("Addto");
        $AddTo->edit($this->_add_to_id,array("status"=>8));
    }

    /**
     * 微信支付失败
     * @param int $_red_id 红包id
     */
    public function wxPayFail()
    {
        Util::appointPost();
        $Mch = $this->newController("MchOrder");
        DB::begin();
        try {
            $Mch->edit($this->_add_to_id,array("status"=>6),"add");
            $AddTo = $this->newController("Addto");
            $AddTo->edit($this->_add_to_id,array("status"=>6));
            $_result = array("code"=>0);
            DB::commit();
        } catch (\PDOException $e) {
            $_result = array("code"=>105);
            DB::back();
        }
        Util::returns($_result);
    }
}